#include "constantField.hpp"
#include "fieldFunctions.hpp"
#include "vtkFunctions.hpp"
#include "vtkFunctions_import.hpp"
#include "magic_enum.hpp"

namespace hms::vtk
{


template<typename SolverType>
void readConstantField(
	const xml::XMLElement* fieldElem,
	SolverBase<SolverType>& solver,
	typename SolverBase<SolverType>::ConstantFieldName fieldName
){
	using MeshType = typename SolverBase<SolverType>::MeshType;

	auto nComponents { getAttributeValue<Index>(fieldElem, nComponentsName) };
	bool isFunction  { getAttributeValue<bool >(fieldElem, "isFunction") };
	auto isUniform   { static_cast<Uniformity>(
		getAttributeValue<bool >(fieldElem, "isUniform")
	)};

	ArrayXXs values;

	resizeFieldValues( values, nComponents, solver.mesh(), isUniform );

	if (isFunction){
		std::vector<FunctionParserWrapper> functions {
			readFunctions(fieldElem, nComponents, false)
		};
		setFieldByFunctions( values, functions, solver, isUniform, true );
	} else {
		textToFieldValues(fieldElem, values, solver.mesh(), isUniform);
	}
	if (isUniform)
		solver.constantField( fieldName ) = ConstantField<Uniform, MeshType>{
			solver.mesh(), std::move(values)
		};
	else
		solver.constantField( fieldName ) = ConstantField<NonUniform, MeshType>{
			solver.mesh(), std::move(values)
		};
}


template<typename SolverType>
void readConstantFields(
	const xml::XMLDocument* doc,
	SolverBase<SolverType>& solver
){
	using S = SolverBase<SolverType>;
	using CFName = typename S::ConstantFieldName;

	const xml::XMLElement* constElem { getChildNodeByName(doc, constNode) };

	for ( int i{0}; i < S::nConstantFields ; ++i ){
		auto fieldName { static_cast<CFName>(i) };
		std::string fieldNameStr { magic_enum::enum_name(fieldName) };

		const xml::XMLElement* fieldElem { getChildNodeByAttributeValue(
			constElem, constChild, "Name", fieldNameStr
		) };

		readConstantField(fieldElem, solver, fieldName);
	}
}

} // namespace hms::vtk
